package main

import (
	"encoding/json"
	"fmt"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	pb "github.com/hyperledger/fabric/protos/peer"
)

type EvidenceStruct struct {
	EvdID string `json:"evdID"`
	Owner string `json:"owner"`
	Content string `json:"content"`
	CreateDate string `json:"createDate"`
	UpdateDate string `json:"updateDate"`
}

type EvidenceChaincode struct {

}

func (EvidenceChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
    return shim.Success(nil)
}

func (t *EvidenceChaincode) storage(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	var evdID string
	var evdStruct EvidenceStruct
	if len(args) != 1{
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}

	evdStructStr := args[0]

	err := json.Unmarshal([]byte(evdStructStr), &evdStruct)
	if err != nil {
		return shim.Error("Args must json data")
	}

	evdID = evdStruct.EvdID
	err = stub.PutState(evdID, []byte(evdStructStr))
	if err != nil {
		return shim.Error("PutState failed, error: " + err.Error())
	}

	return shim.Success([]byte("storage success"))
}

func (t *EvidenceChaincode) update(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	var evdID string
	var evdStructNew EvidenceStruct
	if len(args) != 1{
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}

	evdStructStrNew := args[0]

	err := json.Unmarshal([]byte(evdStructStrNew), &evdStructNew)
	if err != nil {
		return shim.Error("Args must json data")
	}

	evdID = evdStructNew.EvdID
	evdStructBytes, err := stub.GetState(evdID)
	if err != nil {
		return shim.Error("GutState failed, error: " + err.Error())
	}

	var evdStructOld EvidenceStruct
	err = json.Unmarshal(evdStructBytes, &evdStructOld)
	if err != nil {
		return shim.Error("EdStructOld Unmarshal failed, error: " + err.Error())
	}

	evdStructNew.CreateDate = evdStructOld.CreateDate
	evdStructNew.Owner = evdStructOld.Owner

	evdStructNewBytes, err := json.Marshal(evdStructNew)
	if err != nil {
		return shim.Error("evdStructNew Marshal failed, error: " + err.Error())
	}

	err = stub.PutState(evdID, evdStructNewBytes)
	if err != nil {
		return shim.Error("PutState failed, error: " + err.Error())
	}

	return shim.Success([]byte("update success"))
}

func (t *EvidenceChaincode) load(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	var evdID string
	if len(args) != 1{
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}

	evdID = args[0]
	evdStructBytes, err := stub.GetState(evdID)
	if err != nil {
		return shim.Error("GutState failed, error: " + err.Error())
	}

	return shim.Success(evdStructBytes)
}

func (t *EvidenceChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
	function, args := stub.GetFunctionAndParameters()
	if function == "storage" {
		return t.storage(stub, args)
	} else if function == "update" {
		return t.update(stub, args)
	} else if function == "load" {
		return t.load(stub, args)
	}
	return shim.Error("Invalid invoke function name. Expecting \"storage\" \"update\" \"load\"")
}

func main() {
	err := shim.Start(new(EvidenceChaincode))
	if err != nil {
		fmt.Println("Error starting evidence  chaincode: %s", err)
	}
}
